package com.itheima.dubbo.mysql.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.commons.model.domain.UserInfo;
import com.itheima.commons.model.domain.UserLoginDate;
import com.itheima.commons.model.domain.UserStatus;
import com.itheima.commons.model.vo.*;
import com.itheima.dubbo.interfaces.UserInfoApi;
import com.itheima.dubbo.mysql.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

@Service
public class UserInfoApiImpl implements UserInfoApi {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private SettingsMapper settingsMapper;

    @Autowired
    private BlackListMapper blackListMapper;

    @Autowired
    private UserLoginDateMapper userLoginDateMapper;

    @Autowired
    private UserStatusMapper userStatusMapper;


    @Override
    public void addUserInfo(UserInfo userInfo) {
        userInfoMapper.insert(userInfo);
    }

    @Override
    public void updateLogo(Long uid, String pictureURL) {
        userInfoMapper.update(UserInfo.builder().logo(pictureURL).build(),
                Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserId, uid));
    }

    @Override
    public UserInfo findUserInfoByUserId(Long uid) {
        return userInfoMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserId, uid));
    }

    @Override
    public Map<Long, UserInfo> findUserInfoListByUserIds(UserInfo userInfo, List<Long> userIds) {
        // 查询条件  没有传递过来
        List<UserInfo> userInfos = userInfoMapper.selectList(Wrappers.lambdaQuery(UserInfo.class)
                        .in(UserInfo::getUserId, userIds)
                        .eq(ObjectUtil.isNotNull(userInfo.getSex()), UserInfo::getSex, userInfo.getSex())
//                    .eq(ObjectUtil.isNotNull(userInfo.getCity()), UserInfo::getCity, userInfo.getCity())
//                    .le(ObjectUtil.isNotNull(userInfo.getAge()), UserInfo::getAge, userInfo.getAge())
                        .like(ObjectUtil.isNotNull(userInfo.getNickName()), UserInfo::getNickName, userInfo.getNickName())
        );
        Map<Long, UserInfo> infoMap = CollUtil.fieldValueMap(userInfos, "userId");
        return infoMap;
    }

    @Override
    public Map<Long, UserInfo> findUserInfoListByUserIds(List<Long> userIds) {
        List<UserInfo> userInfos = userInfoMapper.selectList(Wrappers.lambdaQuery(UserInfo.class)
                .in(UserInfo::getUserId, userIds));
        Map<Long, UserInfo> infoMap = CollUtil.fieldValueMap(userInfos, "userId");
        return infoMap;
    }

    @Override
    public void updateUserInfoByUserId(UserInfo userInfo) {
        userInfoMapper.update(userInfo, Wrappers.lambdaQuery(UserInfo.class)
                .eq(UserInfo::getUserId, userInfo.getUserId()));
    }


    @Override
    public List<ReturnDataVo> queryPeriodRetentionRate(List<String> dateList) {
        List<ReturnDataVo> returnDataVos = new ArrayList<>();
        for (String date : dateList) {

            //查询每日的新增对象
            List<UserInfo> addUsers = userInfoMapper.selectList(Wrappers.lambdaQuery(UserInfo.class)
                    .like(UserInfo::getCreated, date + "%"));

            //每日的新增user的数量
            Integer addCount = addUsers.size();

            //获取所有的userId集合
            List<Long> userIds = CollUtil.getFieldValues(addUsers, "userId", Long.class);

            //日期加一
            String offsetDay = DateUtil.formatDate(DateUtil.offsetDay(Convert.toDate(date), 1));
            //求第二天的新增用户里的仍然活跃的用户
            QueryWrapper<UserLoginDate> wrapper = new QueryWrapper<>();
            wrapper.select("DISTINCT user_id").like("login_date", offsetDay + "%").in("user_id", userIds);
            Integer secondDayCount = userLoginDateMapper.selectCount(wrapper);

            //求留存率
            Integer retentionRate = secondDayCount / addCount;

            //创建vo对像
            ReturnDataVo returnDataVo = ReturnDataVo.builder().title(Convert.toStr(date)).amount(retentionRate).build();

            //添加到集合里
            returnDataVos.add(returnDataVo);
        }
        return returnDataVos;
    }

    @Override
    public List<ReturnDataVo> queryPeriodActiveUserCount(List<String> dateList) {
        List<ReturnDataVo> returnDataVos = new ArrayList<>();
        for (String date : dateList) {
            String dateStr = Convert.toStr(date);
            ReturnDataVo returnDataVo = new ReturnDataVo();
            QueryWrapper<UserLoginDate> wrapper = new QueryWrapper<>();
            wrapper.select("DISTINCT user_id").like("login_date", dateStr + "%");
            Integer count = userLoginDateMapper.selectCount(wrapper);
            returnDataVo.setTitle(dateStr);
            returnDataVo.setAmount(count);
            returnDataVos.add(returnDataVo);
        }
        return returnDataVos;
    }

    @Override
    public List<ReturnDataVo> queryPeriodNewUserCount(List<String> dateList) {
        List<ReturnDataVo> returnDataVos = new ArrayList<>();
        for (String date : dateList) {
            String dateStr = Convert.toStr(date);
            ReturnDataVo returnDataVo = new ReturnDataVo();
            Integer count = userInfoMapper.selectCount(Wrappers.lambdaQuery(UserInfo.class)
                    .like(UserInfo::getCreated, dateStr + "%"));
            returnDataVo.setTitle(dateStr);
            returnDataVo.setAmount(count);
            returnDataVos.add(returnDataVo);
        }
        return returnDataVos;
    }

    @Override
    public LocalTotalVo queryNewUserArea(String area, List<String> list, List<Long> userIds) {
        Integer count = 0;
        for (String province : list) {
            count = count + userInfoMapper.selectCount(Wrappers.lambdaQuery(UserInfo.class)
                    .like(UserInfo::getCity, province + "%")
                    .in(UserInfo::getUserId, userIds));
        }
        return LocalTotalVo.builder().title(area).amount(count).build();
    }

    @Override
    public List<LocalDistributionVo> queryNewUserProvinceCount(List<String> provinceList, List<Long> userIds) {
        List<LocalDistributionVo> localDistributionVos = new ArrayList<>();
        for (String province : provinceList) {
            LocalDistributionVo localDistributionVo = new LocalDistributionVo();
            Integer count = userInfoMapper.selectCount(Wrappers.lambdaQuery(UserInfo.class)
                    .like(UserInfo::getCity, province + "%")
                    .in(UserInfo::getUserId, userIds));
            localDistributionVo.setTitle(province);
            localDistributionVo.setAmount(count);
            localDistributionVos.add(localDistributionVo);
        }
        return localDistributionVos;
    }

    @Override
    public List<GenderDistributionVo> queryNewUserGenderCount(List<Integer> sexList, List<Long> userIds) {
        List<GenderDistributionVo> genderDistributionVos = new ArrayList<>();
        for (Integer sex : sexList) {
            GenderDistributionVo genderDistributionVo = new GenderDistributionVo();
            String gender = "男性用户";
            if (sex == 1) {
                gender = "男性用户";
            } else if (sex == 2) {
                gender = "女性用户";
            } else if (sex == 3) {
                gender = "未知性别用户";
            }
            Integer count = userInfoMapper.selectCount(Wrappers.lambdaQuery(UserInfo.class)
                    .eq(UserInfo::getSex, sex)
                    .in(UserInfo::getUserId, userIds));
            genderDistributionVo.setTitle(gender);
            genderDistributionVo.setAmount(count);
            genderDistributionVos.add(genderDistributionVo);
        }

        return genderDistributionVos;
    }

    @Override
    public List<IndustryDistributionVo> queryNewUserIndustryCount(List<Long> userIds, List<String> industryStrList) {
        List<IndustryDistributionVo> industryDistributionVos = new ArrayList<>();
        for (String industry : industryStrList) {
            IndustryDistributionVo industryDistributionVo = new IndustryDistributionVo();
            Integer count = userInfoMapper.selectCount(Wrappers.lambdaQuery(UserInfo.class)
                    .eq(UserInfo::getIndustry, industry)
                    .in(UserInfo::getUserId, userIds));
            industryDistributionVo.setTitle(industry);
            industryDistributionVo.setAmount(count);
            industryDistributionVos.add(industryDistributionVo);
        }
        return industryDistributionVos;
    }

    @Override
    public List<UserInfo> queryUserByCreateDate(String startDate, String endDate) {
        List<UserInfo> userInfos = userInfoMapper.selectList(Wrappers.lambdaQuery(UserInfo.class).between(UserInfo::getCreated, startDate + " 00:00:00", endDate + " 23:59:59"));
        return userInfos;
    }

    @Override
    public Long queryOneDayActiveUser(Date date) {
        //每天的活跃用户，需去重
        String dateStr = DateUtil.formatDate(date);
        QueryWrapper<UserLoginDate> wrapper = new QueryWrapper<>();
        wrapper.select("DISTINCT user_id").like("login_date", dateStr + "%");
        return Convert.toLong(userLoginDateMapper.selectCount(wrapper));
    }

    @Override
    public void updateUserStatusByUserId(Long userId, String userStatus) {
        userStatusMapper.update(UserStatus.builder()
                .userStatus(userStatus).build(), Wrappers.lambdaQuery(UserStatus.class).eq(UserStatus::getUserId, userId));
    }

    @Override
    public List<UserStatus> queryAllUserStatusMatchFields(List<Long> userIds) {
        return userStatusMapper.selectList(Wrappers.lambdaQuery(UserStatus.class)
                .in(UserStatus::getUserId, userIds));
    }

    @Override
    public List<UserInfo> queryAllUserInfoMatchFields(Integer page, Integer pagesize, String nickname, String city) {
        Page<UserInfo> userInfoPage = userInfoMapper.selectPage(new Page<>(page, pagesize),
                Wrappers.lambdaQuery(UserInfo.class)
                        .eq(StrUtil.isNotBlank(nickname), UserInfo::getNickName, nickname)
                        .like(StrUtil.isNotBlank(city), UserInfo::getCity, city + "%"));
        return userInfoPage.getRecords();
    }

    @Override
    public UserStatus queryUserStatusByUid(Long userId) {
        return userStatusMapper.selectOne(Wrappers.lambdaQuery(UserStatus.class).eq(UserStatus::getUserId, userId));
    }

    @Override
    public List<UserInfo> queryUserInfoList(Set<Long> userIds) {
        QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("user_id", userIds);
        return userInfoMapper.selectList(queryWrapper);
    }
}
